# 13.Vue2 vs Vue3
# 关于 Vue3 的 setup
- setup()函数接收两个参数:props、context(包含 attrs、slots、emit)。
- setup 函数是处于生命周期 beforeCreated 和 created 俩个钩子函数之前。
- 执行 setup 时,组件实例尚未被创建(在 setup()内部,this 不会是该活跃实例得引用,即不指向 vue 实例,Vue 为了避免我们错误得使用,直接将 setup 函数中得 this 修改成了 undefined)。
- 与模板一起使用时,需要返回一个对象。
- 因为 setup 函数中,props 是响应式得,当传入新的 prop 时,它将会被更新,所以不能使用 es6 解构,因为它会消除 prop 得响应性,如需解构 prop,可以通过使用 setup 函数中得 toRefs 来完成此操作。
- 在 setup()内使用响应式数据时,需要通过 .value 获取。
- 从 setup() 中返回得对象上得 property 返回并可以在模板中被访问时,它将自动展开为内部值。不需要在模板中追加.value。
- setup 函数只能是同步的不能是异步的。
# 差异
# diff 算法
- Vue2 与 Vue3 的 diff 算法主要区别是处理完首尾节点后,对剩余节点的处理方式。
vue2 使用双端比较,时间复杂度为 O(n^3),全量比较
- 头头,尾尾比较
- 头尾,尾头比较
- 尽可能复用
- https://juejin.cn/post/7078187020832473125
vue3 使用最长递增子序列,时间复杂度为 O(n^2)
- https://juejin.cn/post/6937243374453784613
- https://blog.csdn.net/tianlu930/article/details/136019824#:~:text=%E5%8F%8C%E7%AB%AFdiff%E7%AE%97%E6%B3%95%E6%98%AF%E7%AE%80%E5%8D%95diff%E7%AE%97%E6%B3%95%E7%9A%84%E4%BC%98%E5%8C%96%E7%89%88%E6%9C%AC%EF%BC%8C%E6%98%AF%E6%AF%94%E8%BE%83%E4%B8%A4%E4%B8%AA%E6%95%B0%E7%BB%84%E4%B9%8B%E9%97%B4%E7%9A%84%E5%B7%AE%E5%BC%82%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%9C%A8%E4%B8%8D%E4%BD%BF%E7%94%A8%E9%80%92%E5%BD%92%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%E6%AF%94%E8%BE%83%E6%95%B0%E7%BB%84%EF%BC%8C%E4%BB%8E%E8%80%8C%E6%8F%90%E9%AB%98%E6%95%88%E7%8E%87%E3%80%82%20%E5%AE%83%E5%8F%AF%E4%BB%A5%E5%A4%84%E7%90%86%E6%9B%B4%E5%A4%8D%E6%9D%82%E7%9A%84%E5%9C%BA%E6%99%AF%EF%BC%8C%E6%AF%94%E5%A6%82%E7%A7%BB%E5%8A%A8%E4%BA%86%E5%85%83%E7%B4%A0%20vue3.x%E5%B0%B1%E6%98%AF%E4%BD%BF%E7%94%A8%E7%9A%84%E5%8F%8C%E7%AB%AFdiff%E7%AE%97%E6%B3%95%20%E5%AE%9E%E7%8E%B0%E6%80%9D%E8%B7%AF%E6%98%AF%E4%BB%8E%E6%95%B0%E7%BB%84%E4%B8%A4%E7%AB%AF%E5%BC%80%E5%A7%8B%E9%81%8D%E5%8E%86%EF%BC%8C%E6%AF%94%E8%BE%83%E7%9B%B8%E9%82%BB%E5%85%83%E7%B4%A0%E6%98%AF%E5%90%A6%E7%9B%B8%E5%90%8C%EF%BC%8C%E7%9B%B8%E5%90%8C%E5%88%99%E6%AF%94%E8%BE%83%E4%B8%8B%E4%B8%80%E5%AF%B9%E5%85%83%E7%B4%A0%EF%BC%9B%E5%A6%82%E6%9E%9C%E4%B8%8D%E5%90%8C%EF%BC%8C%E5%B0%B1%E6%A0%87%E8%AE%B0%E4%B8%BA%E5%88%A0%E9%99%A4%E6%88%96%E6%B7%BB%E5%8A%A0%EF%BC%8C%E5%B9%B6%E7%BB%A7%E7%BB%AD%E9%81%8D%E5%8E%86%20%E7%BC%BA%E7%82%B9%E7%9A%84%E8%AF%9D%E5%B0%B1%E5%8F%AA%E8%83%BD%E6%AF%94%E8%BE%83%E5%BA%8F%E5%88%97%E7%B1%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%8C%E4%B8%8D%E8%83%BD%E6%AF%94%E8%BE%83%E6%A0%91%E5%BD%A2%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%20Vue3,diff%E7%AE%97%E6%B3%95%E8%BF%87%E7%A8%8B%20%E6%96%B0%E6%97%A7%E8%8A%82%E7%82%B9%E4%BB%8E%E5%A4%B4%E5%BC%80%E5%A7%8B%E6%AF%94%E8%BE%83%EF%BC%8C%E7%9B%B8%E5%90%8C%E7%9B%B4%E6%8E%A5%E5%A4%8D%E7%94%A8%E6%89%A7%E8%A1%8C%20patch%20%EF%BC%8C%E7%9B%B4%E5%88%B0%E6%AF%94%E8%BE%83%E5%88%B0%E4%B8%A4%E8%8A%82%E7%82%B9%E4%B8%8D%E5%90%8C%E4%B8%BA%E6%AD%A2%E3%80%82%20%E6%96%B0%E6%97%A7%E8%8A%82%E7%82%B9%E4%BB%8E%E5%B0%BE%E5%BC%80%E5%A7%8B%E6%AF%94%E8%BE%83%EF%BC%8C%E7%9B%B8%E5%90%8C%E7%9B%B4%E6%8E%A5%E5%A4%8D%E7%94%A8%E6%89%A7%E8%A1%8C%20patch%20%EF%BC%8C%E7%9B%B4%E5%88%B0%E6%AF%94%E8%BE%83%E5%88%B0%E4%B8%A4%E8%8A%82%E7%82%B9%E4%B8%8D%E5%90%8C%E4%B8%BA%E6%AD%A2%E3%80%82
双向绑定原理不同 vue2:
vue2 的双向数据绑定是利用 ES5 的一个 APIObject.definePropert() 对数据进行劫持,结合发布订阅模式的方式来实现的。 vue3:
vue3 中使用了 ES6 的 Proxy API 对数据代理。相比 vue2.x,使用 proxy 的优势如下:
- defineProperty 只能监听某个属性,不能对全对象监听
- 可以省去 for in,闭包等内容来提升效率(直接绑定整个对象即可)
- 可以监听数组,不用再去单独的对数组做特异性操作 vue3.x 可以检测到数组内部数据的变化。
是否支持碎片 vue2:vue2 不支持碎片。 vue3:vue3 支持碎片(Fragments),就是说可以拥有多个根节点。
API 类型不同 Vue2:选项型 API(Options API) Vue3:组合式 API(Composition API)
定义数据变量和方法不同 vue2:vue2 是把数据放入 data 中,在 vue2 中定义数据变量是 data(){},创建的方法要在 methods:{}中。 vue3:,vue3 就需要使用一个新的 setup()方法,此方法在组件初始化构造的时候触发。使用以下三个步骤来建立反应性数据: 1. 从 vue 引入 reactive; 2. 使用 reactive() 方法来声明数据为响应性数据; 3. 使用 setup()方法来返回我们的响应性数据,从而 template 可以获取这些响应性数据。
生命周期钩子函数不同 vue2:vue2 中的生命周期:
beforeCreate 组件创建之前 created 组件创建之后 beforeMount 组价挂载到页面之前执行 mounted 组件挂载到页面之后执行 beforeUpdate 组件更新之前 updated 组件更新之后
vue3:vue3 中的生命周期:
setup 开始创建组件 onBeforeMount 组价挂载到页面之前执行 onMounted 组件挂载到页面之后执行 onBeforeUpdate 组件更新之前 onUpdated 组件更新之后 而且 vue3.x 生命周期在调用前需要先进行引入。除了这些钩子函数外,vue3.x 还增加了 onRenderTracked 和 onRenderTriggered 函数。
父子传参不同 vue2:父传子,用 props,子传父用事件 Emitting Events。在 vue2 中,会调用 this$emit 然后传入事件名和对象。 vue3:父传子,用 props,子传父用事件 Emitting Events。在 vue3 中的 setup()中的第二个参数 content 对象中就有 emit,那么我们只要在 setup()接收第二个参数中使用分解对象法取出 emit 就可以在 setup 方法中随意使用了。
指令与插槽不同 vue2:vue2 中使用 slot 可以直接使用 slot;v-for 与 v-if 在 vue2 中优先级高的是 v-for 指令,而且不建议一起使用。 vue3:vue3 中必须使用 v-slot 的形式;vue3 中 v-for 与 v-if,只会把当前 v-if 当做 v-for 中的一个判断语句,不会相互冲突;vue3 中移除 keyCode 作为 v-on 的修饰符,当然也不支持 config.keyCodes;vue3 中移除 v-on.native 修饰符;vue3 中移除过滤器 filter。
main.js 文件不同 vue2:vue2 中我们可以使用 pototype(原型)的形式去进行操作,引入的是构造函数。 vue3:vue3 中需要使用结构的形式进行操作,引入的是工厂函数;vue3 中 app 组件中可以没有根标签。
Dom diff 算法不同
Vue3:
- 对静态数据进行了标记,在 diff 算法时直接跳过,只会被创建一次,在渲染时直接复用。
- tree-shaking 对不用的代码进行删除